package cn.i7baozh.starter.client.config;

import cn.i7baozh.starter.client.handler.SentinelBlockedHandler;
import cn.i7baozh.starter.client.interceptor.OpenFeignLoggingInterceptor;
import cn.i7baozh.starter.client.loadbalancer.SameClusterGroupGroupLoadBalancer;
import cn.i7baozh.starter.common.controller.GatewayRestClientApiHandler;
import cn.i7baozh.starter.common.interceptor.ErrorResultInterceptor;
import cn.i7baozh.starter.common.interceptor.RequestLoggingInterceptor;
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import feign.RequestInterceptor;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

/**
 * @author : baoqi.zhang
 * @date :   2022/5/12 15:17
 */
@Configuration
public class ApplicationContextConfig {

    @Bean
    public GatewayRestClientApiHandler restClientApiHandler() {
        return new GatewayRestClientApiHandler();
    }

    @Bean
    public RequestLoggingInterceptor requestLoggingInterceptor() {
        return new RequestLoggingInterceptor();
    }

    @Bean
    public ErrorResultInterceptor errorResultInterceptor() {
        return new ErrorResultInterceptor();
    }

    @Bean
    public RequestInterceptor requestInterceptor() {
        return new OpenFeignLoggingInterceptor();
    }
    @Bean
    public BlockExceptionHandler sentinelBlockedHandler() {
        return new SentinelBlockedHandler();
    }

    /**
     * 模块负载均衡配置
     */
    @LoadBalancerClient(value = "starter-service", configuration = StarterServiceLoadBalanceConfigClient.class)
    public class StarterServiceLoadBalanceConfigClient{
        @Bean
        public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment,
                                                                                       LoadBalancerClientFactory loadBalancerClientFactory,
                                                                                       NacosDiscoveryProperties nacosDiscoveryProperties) {
            String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
            return new SameClusterGroupGroupLoadBalancer(
                    loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name, nacosDiscoveryProperties);
        }
    }
}
